﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.Security;
using GameSchool.Models;
using GameSchool.Models.AccountModels;

namespace GameSchool.DAL
{
    public class AccountRepository : IAccountRepository
    {
        // Nánari upplýsingar um hvernig Repository patternið virkar er á:
        // http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

        /// <summary>
        /// Meðlimabreyta sem er gagnagrunnstengingin
        /// </summary>
        private gsEntities m_db;

        /// <summary>
        /// Class Initializer sem tekur við gagnagrunnstengingu sem skal nota
        /// </summary>
        /// <param name="db"></param>
        public AccountRepository(gsEntities db)
        {
            this.m_db = db;
        }

        /// <summary>
        /// Listi yfir allar deildir og prófgráður í þeim
        /// </summary>
        /// <returns>Lista</returns>
        public List<vDepartmentDegrees> GetDepartmentDegrees()
        {
            return m_db.vDepartmentDegrees.OrderBy(o => o.DepartmentDegreeName).ToList();
        }

        /// <summary>
        /// Listi yfir öll póstnúmer á Íslandi
        /// </summary>
        /// <returns>Lista</returns>
        public List<vPostalCodes> GetPostalCodes()
        {
            return m_db.vPostalCodes.OrderBy(o => o.PostalCodeRegion).ToList();
        }

        /// <summary>
        /// Skilar lista yfir öll prófin
        /// </summary>
        /// <returns></returns>
        public List<UserModel> GetUsers()
        {
            var aspnetUsers = m_db.vUsers.ToList();
            var users = aspnetUsers.Select(u => this.GetUserById(u.UserId)).ToList();

            return users.OrderBy(o => o.FullName).ToList();
        }

        /// <summary>
        /// Leitar að notanda eftir UserID
        /// </summary>
        /// <param name="userId"> </param>
        /// <returns></returns>
        public UserModel GetUserById(Guid userId)
        {
            var dbUser = m_db.vUsers.SingleOrDefault(u => u.UserId == userId);
            var userProfile = AccountProfile.GetProfileByUserName(dbUser.UserName);
            var user = new UserModel
                           {
                               UserId = dbUser.UserId,
                               FullName = userProfile.FullName,
                               SSN = userProfile.SSN,
                               Gender = userProfile.Gender,
                               Street = userProfile.Street,
                               PostalCode = userProfile.PostalCode,
                               Country = userProfile.Country,
                               PhoneNumber = userProfile.PhoneNumber,
                               UserType =
                                   (AccountProperties.UserType)
                                   Enum.Parse(typeof(AccountProperties.UserType), dbUser.UserType, true),
                               DepartmentDegreeId = userProfile.DepartmentDegreeId,
                               UserName = userProfile.UserName,
                               Email = dbUser.Email
                           };

            return user;
        }

        /*
        /// <summary>
        /// Bætir við prófi í gagnagrunninn. ATH: Vistar ekki sjálfkrafa
        /// </summary>
        /// <param name="exam"></param>
        public void InsertExam(Exam exam)
        {
            m_db.Exam.AddObject(exam);
        }

        /// <summary>
        /// Eyðir prófi úr gagnagrunninum. ATH: Vistar ekki sjálfkrafa
        /// </summary>
        /// <param name="examId"></param>
        public void DeleteExam(int examId)
        {
            // Við skulum ekkert gera sérstakt hérna þar sem við viljum ekki leyfa að eyða prófum.
            // Annars væri kóðinn fyrir það svona:

            //var toDelete = m_db.Exam.SingleOrDefault(e => e.ExamID == examId);
            //m_db.Exam.DeleteObject(toDelete);
            //m_db.SaveChanges();
        }
        */

        /// <summary>
        /// Uppfærir próf í gagnagrunninum. ATH: Vistar ekki sjálfkrafa
        /// </summary>
        /// <param name="exam"></param>
        public void UpdateUser(UserModel userToUpdate)
        {
            var memberShipUser = Membership.GetUser(userToUpdate.UserId);

            try
            {
                // Reyna að uppfæra notandann í membership klasanum
                memberShipUser.Email = userToUpdate.Email;

                // Uppfæra 
                var userProfile = AccountProfile.GetProfileByUserName(memberShipUser.UserName);
                userProfile.FullName = userToUpdate.FullName;
                userProfile.SSN = userToUpdate.SSN;
                userProfile.Gender = userToUpdate.Gender;
                userProfile.Street = userToUpdate.Street;
                userProfile.PostalCode = userToUpdate.PostalCode;
                userProfile.Country = userToUpdate.Country;
                userProfile.PhoneNumber = userToUpdate.PhoneNumber;
                userProfile.DepartmentDegreeId = userToUpdate.DepartmentDegreeId;
            }
            finally
            {
                Membership.UpdateUser(memberShipUser);
            }

        }

        /// <summary>
        /// Vistar breytingar sem gerðar voru í sessioninu
        /// </summary>
        public void Save()
        {
            m_db.SaveChanges();
        }

        #region Disposerinn fyrir using() statement - Alltaf eins

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    m_db.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}